﻿#include "initwidget.h"
#include "ui_initwidget.h"
#include <QMessageBox>
#include <QDateTime>
#include <QMovie>
#include <QTextStream>
#include <QTimer>
#include <QTranslator>
#include <opencv2/opencv.hpp>
#include <Thread/imagenamer.h>
#include <Alg/weldingalgorithmmanager.h>
#include <Common/SysEnv.h>

InitWidget::InitWidget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::InitWidget)
{
    ui->setupUi(this);
    setWindowIcon(QIcon(":icon/app.ico"));
    setWindowFlags(Qt::FramelessWindowHint | Qt::Window | Qt::WindowMinimizeButtonHint);
    connect(ui->btnMin,&QPushButton::clicked,this,&InitWidget::windowMin);
    connect(ui->btnMax,&QPushButton::clicked,this,&InitWidget::windowMax);
    connect(ui->btnClose,&QPushButton::clicked,this,&InitWidget::windowClose);

    connect(&SysEnv::instance(), &SysEnv::initDone,
            [this](quint8 m){
                updateModuleStatus(m);
            });
    qRegisterMetaType<WeldingResult>("WeldingResult");

    initWindow();
    initMenuBar();

    loadQssFile();

    ui->btnMax->hide();

    m_timer = new QTimer(this);
    connect(m_timer, SIGNAL(timeout()), this, SLOT(updateTime()));
    m_timer->start(1000);

    // 添加清理定时器
    m_cleanupTimer = new QTimer(this);
    connect(m_cleanupTimer, &QTimer::timeout, this, &InitWidget::cleanupExpiredImages);

    windowMax();
    Alg::WeldingAlgorithmManager::instance().initialize();

    // 程序启动时执行一次清理，并安排每日清理
    cleanupExpiredImages();
    scheduleDailyCleanup();
}

InitWidget::~InitWidget()
{
    // 停止所有定时器
    if (m_timer) {
        m_timer->stop();
    }
    if (m_cleanupTimer) {
        m_cleanupTimer->stop();
    }

    delete ui;
}

void InitWidget::initWindow()
{
    isMaxWin=true;
    ui->btnMax->setIcon(QIcon(":/img/max.png"));
    ui->btnMin->setIcon(QIcon(":/img/minimize.png"));
    ui->btnClose->setIcon(QIcon(":/img/close.png"));
    ui->textLogo->setPixmap(QPixmap(":/img/logo.png"));
    ui->textLogo->setScaledContents(true);
    qRegisterMetaType<QList<WeldingResult>>("QList<WeldingResult>");

    m_triForm = new CapSenseTriForm(this);
    this->addWidget(m_triForm);

    m_ioForm = new ioActionForm();
    m_algorithmTester = new AlgorithmTester();
    m_saveForm = new SaveForm();
    // 添加清除数据连接
    connect(m_ioForm, &ioActionForm::clearDataRequested, m_triForm, &CapSenseTriForm::onClearData);

    connect(m_triForm, &CapSenseTriForm::sigCamResult, m_algorithmTester, &AlgorithmTester::onAlgorithmFinished);
    connect(m_triForm, &CapSenseTriForm::sigFramResult, m_ioForm, &ioActionForm::slotFrameInfo);
    connect(m_saveForm, &SaveForm::sigSaveStateChanged, this, &InitWidget::upSaveImg);
    connect(m_saveForm, &SaveForm::sigSavePathChanged, this, &InitWidget::upSavePath);
    connect(&SysEnv::instance(),&SysEnv::runningChanged,m_triForm, &CapSenseTriForm::onSysRuning);

    m_algConfigForm = new AlgConfigForm();
}

void InitWidget::updateModuleStatus(quint8 statusBits)
{
    QString camA = (statusBits & SysEnv::CAM_A) ? tr("CamA: Failed") : tr("CamA: OK");
    QString camB = (statusBits & SysEnv::CAM_B) ? tr("CamB: Failed") : tr("CamB: OK");
    QString algo = (statusBits & SysEnv::ALGO)  ? tr("Algorithm: Failed") : tr("Algorithm: OK");
    QString plc  = (statusBits & SysEnv::PLC)   ? tr("PLC: Failed") : tr("PLC: OK");

    ui->textModuleStatus->setText(QString("%1 | %2 | %3 | %4")
                                      .arg(camA, camB, algo, plc));


    // m_ioAction->setEnabled(!(statusBits & SysEnv::PLC));   // PLC 失败就禁用 IO
    // m_localTestAction->setEnabled(!(statusBits & SysEnv::ALGO)); // Algo 失败就禁用本地测试

    QString style = "QLabel { padding: 2px 5px; border-radius: 3px; ";
    if (statusBits != 240) {
        style += "background-color: #ffcccc; color: #990000;";
        SysEnv::instance().setRunning(false);
    } else {
        style += "background-color: #ccffcc; color: #006600;";//全部成功
        SysEnv::instance().setRunning(true);
    }
    style += " }";
    ui->textModuleStatus->setStyleSheet(style);
}

void InitWidget::initMenuBar()
{
    m_menuBar = ui->menuBar;

    /* 1. Run Mode ------------------------------------------------------ */
    QMenu *runMenu = m_menuBar->addMenu(tr("Run(&R)"));
    m_ioAction = runMenu->addAction(tr("IO Channel (PLC)"));
    m_localTestAction = runMenu->addAction(tr("Local Test (Algo Debug)"));
    connect(m_ioAction,    &QAction::triggered, this, &InitWidget::onIoChannel);
    connect(m_localTestAction, &QAction::triggered, this, &InitWidget::onLocalTest);

    /* 2. System Config ------------------------------------------------- */
    QMenu *setMenu = m_menuBar->addMenu(tr("Settings(&S)"));
    QAction *algoAction = setMenu->addAction(tr("Algorithm Parameters"));
    QAction *saveAction = setMenu->addAction(tr("Save Image Settings"));
    connect(algoAction, &QAction::triggered, this, &InitWidget::onAlgoParam);
    connect(saveAction, &QAction::triggered, this, &InitWidget::onSaveImageCfg);

    /* 3. Data Management ----------------------------------------------- */
    QMenu *dataMenu = m_menuBar->addMenu(tr("Data(&D)"));  // 添加数据管理菜单
    m_historyDataAction = dataMenu->addAction(tr("History Data Query"));
    connect(m_historyDataAction, &QAction::triggered, this, &InitWidget::onHistoryData);

    /* 4. About --------------------------------------------------------- */
    QMenu *helpMenu = m_menuBar->addMenu(tr("Help(&H)"));
    QAction *verAction   = helpMenu->addAction(tr("Version Info"));
    QAction *vendorAction = helpMenu->addAction(tr("Vendor Info"));
    connect(verAction,   &QAction::triggered, this, &InitWidget::onVersionInfo);
    connect(vendorAction,&QAction::triggered, this, &InitWidget::onVendorInfo);

    // m_ioAction->setEnabled(false);
    // m_localTestAction->setEnabled(false);
}

void InitWidget::loadQssFile()
{
    QFile file(":/qss/initForm.qss");
    if (file.open(QFile::ReadOnly))
    {
        QTextStream filetext(&file);
        QString stylesheet = filetext.readAll();
        this->setStyleSheet(stylesheet);
        file.close();
    }
}

void InitWidget::addWidget(QWidget *widget)
{
    ui->horizontalLayout->insertWidget(1,widget);
}

void InitWidget::mousePressEvent(QMouseEvent *event)
{
    if(event->button() == Qt::LeftButton)
    {
        isPressed=true;
        curPos = event->pos();
    }
}

void InitWidget::mouseMoveEvent(QMouseEvent *event)
{
    if(isPressed)
    {
        //当窗口最大化或最小化时也不进行触发
        if(InitWidget::isMaximized() || InitWidget::isMinimized())
        {
            return;
        }
        else
        {
            //当在按钮之类需要鼠标操作的地方不进行触发(防误触)
            if (ui->btnClose->underMouse()||ui->btnMax->underMouse()||ui->btnMin->underMouse())
            {
                return;
            }
            if(ui->titleWidget->underMouse())
            {
                this->move(event->pos()-curPos+this->pos());    //窗口移动
            }
        }
    }
    event->accept();
}

void InitWidget::mouseReleaseEvent(QMouseEvent *event)
{
    isPressed = false;
}

void InitWidget::mouseDoubleClickEvent(QMouseEvent *event)
{
    Q_UNUSED(event)

    if(ui->titleWidget->underMouse())
    {
        isMaxWin=!isMaxWin;
        if(isMaxWin)
        {

            this->showNormal();
            ui->btnMax->setIcon(QIcon(":/img/max.png"));
        }
        else
        {
            this->showMaximized();
            ui->btnMax->setIcon(QIcon(":/img/mini.png"));
        }
    }
}

void InitWidget::windowMin()
{
    this->showMinimized();
}

void InitWidget::windowMax()
{
    isMaxWin=!isMaxWin;
    if(isMaxWin)
    {
        this->showNormal();
        ui->btnMax->setIcon(QIcon(":/img/max.png"));
    }
    else
    {
        this->showMaximized();
        ui->btnMax->setIcon(QIcon(":/img/mini.png"));
    }
}

void InitWidget::windowClose()
{
    if(!QMessageBox::information(this, tr("info"), tr("Exit the App!"), "Yes", "No")){
        emit appQuit();
        qApp->exit();
    }
}

void InitWidget::show()
{
    this->setVisible(true);
}

void InitWidget::updateTime()
{
    QDateTime time=QDateTime::currentDateTime();
    QString timeText = time.toString("yyyy-MM-dd hh:mm:ss dddd");
    ui->textTime->setText(timeText);
}

void InitWidget::upSaveImg()
{
    m_triForm->setSaveForm(m_saveForm);
}

void InitWidget::upSavePath(const QString &newPath)
{
    m_triForm->upSaveImgPath(newPath);
}

void InitWidget::onIoChannel()
{
    m_ioForm->show();
    m_ioForm->raise();
    m_ioForm->activateWindow();
}

void InitWidget::onLocalTest()
{
    m_algorithmTester->show();
    m_algorithmTester->raise();
    m_algorithmTester->activateWindow();
}

void InitWidget::onAlgoParam()
{
    m_algConfigForm->show();
    m_algConfigForm->raise();
    m_algConfigForm->activateWindow();
}

void InitWidget::onSaveImageCfg()
{
    m_saveForm->show();
    m_saveForm->raise();
    m_saveForm->activateWindow();
}

void InitWidget::onHistoryData()
{
    DataForm *dataForm = new DataForm();
    dataForm->setObjectName("dataForm");
    dataForm->show();
}

void InitWidget::onCameraInfo()
{
}

void InitWidget::onLiveImage()
{
}

void InitWidget::onVersionInfo()
{
}

void InitWidget::onVendorInfo()
{
}

void InitWidget::switchLanguage(const QString &lang)
{
    static QTranslator *current = nullptr;
    if (current) { qApp->removeTranslator(current); delete current; }

    current = new QTranslator(this);
    current->load(lang == "zh" ? ":/i18n/MzWeldSight_cn.qm"
                               : ":/i18n/MzWeldSight_en.qm");
    qApp->installTranslator(current);
}

void InitWidget::retranslateMenuBar()
{
}

// 添加清理函数实现
void InitWidget::cleanupExpiredImages()
{
    QString imageSavePath = SysEnv::instance().getImageSavePath();
    int saveDays = SysEnv::instance().getImageSaveDays();

    if (imageSavePath.isEmpty() || saveDays <= 0) {
        qDebug() << "Invalid save path or save days, skip cleanup";
        scheduleDailyCleanup();
        return;
    }

    QDir saveDir(imageSavePath);
    if (!saveDir.exists()) {
        qDebug() << "Save directory does not exist, skip cleanup:" << imageSavePath;
        scheduleDailyCleanup();
        return;
    }

    QDateTime cutoffTime = QDateTime::currentDateTime().addDays(-saveDays);
    qDebug() << "Starting image cleanup. Cutoff time:" << cutoffTime.toString("yyyyMMdd")
             << "Save days:" << saveDays;

    int deletedCount = 0;
    int errorCount = 0;

    // 递归清理所有子目录中的过期文件
    cleanupDirectoryRecursive(imageSavePath, cutoffTime, deletedCount, errorCount);

    qDebug() << "Image cleanup completed. Deleted:" << deletedCount
             << "files, Errors:" << errorCount;

    // 清理完成后重新安排下一次清理
    scheduleDailyCleanup();
}

void InitWidget::cleanupDirectoryRecursive(const QString &directoryPath, const QDateTime &cutoffTime,
                                           int &deletedCount, int &errorCount)
{
    QDir dir(directoryPath);
    if (!dir.exists()) {
        return;
    }

    // 获取目录中的所有条目
    QFileInfoList entries = dir.entryInfoList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot);

    foreach (const QFileInfo &entry, entries) {
        if (entry.isDir()) {
            // 递归处理子目录
            cleanupDirectoryRecursive(entry.absoluteFilePath(), cutoffTime, deletedCount, errorCount);

            // 检查目录是否为空，如果为空则删除
            // QDir subDir(entry.absoluteFilePath());
            // if (subDir.isEmpty()) {
            //     if (subDir.rmdir(entry.absoluteFilePath())) {
            //         qDebug() << "Removed empty directory:" << entry.absoluteFilePath();
            //     }
            // }
        } else if (entry.isFile()) {
            // 从文件名中提取时间信息来判断是否过期
            if (isFileExpired(entry.fileName(), cutoffTime)) {
                if (QFile::remove(entry.absoluteFilePath())) {
                    deletedCount++;
                    qDebug() << "Deleted expired file:" << entry.fileName();
                } else {
                    errorCount++;
                    qWarning() << "Failed to delete file:" << entry.absoluteFilePath();
                }
            }
        }
    }
}

bool InitWidget::isFileExpired(const QString &fileName, const QDateTime &cutoffTime)
{
    // 根据 CameraSaverWorker 中的命名规则解析文件名
    // 文件名格式: yyyyMMdd_HHmmss_zzz_Txxx_Cxx_type.jpg
    // 例如: 20240115_143045_123_T001_C01_composite.jpg

    QRegularExpression timePattern(R"(^(\d{4})(\d{2})(\d{2})_(\d{2})(\d{2})(\d{2})_\d+_)");
    QRegularExpressionMatch match = timePattern.match(fileName);

    if (match.hasMatch()) {
        // 从文件名中提取日期时间
        int year = match.captured(1).toInt();
        int month = match.captured(2).toInt();
        int day = match.captured(3).toInt();
        int hour = match.captured(4).toInt();
        int minute = match.captured(5).toInt();
        int second = match.captured(6).toInt();

        QDateTime fileTime = QDateTime(QDate(year, month, day), QTime(hour, minute, second));

        if (fileTime.isValid()) {
            return fileTime < cutoffTime;
        }
    }

    // 如果无法从文件名解析时间，使用文件的最后修改时间作为备选方案
    QFileInfo fileInfo(fileName);
    if (fileInfo.exists()) {
        return fileInfo.lastModified() < cutoffTime;
    }

    return false;
}

void InitWidget::scheduleDailyCleanup()
{
    // 计算距离下一次清理的时间（毫秒）
    QDateTime now = QDateTime::currentDateTime();
    QDateTime nextCleanup = now.addDays(1);
    nextCleanup.setTime(QTime(2, 0, 0)); // 设置为第二天凌晨2点

    // 如果已经过了今天的2点，就安排到明天
    if (nextCleanup < now) {
        nextCleanup = nextCleanup.addDays(1);
    }

    qint64 interval = now.msecsTo(nextCleanup);

    // 设置单次定时器，触发后重新安排
    m_cleanupTimer->setSingleShot(true);
    m_cleanupTimer->start(interval);

    qDebug() << "Next image cleanup scheduled at:" << nextCleanup.toString("yyyy-MM-dd hh:mm:ss")
             << "in" << (interval / 1000 / 3600.0) << "hours";
}
